package com.learn.singleton004;

import java.util.concurrent.TimeUnit;

/**单例模式-双重检查-线程安全[推荐用]
 * @author 1
 */
public class SingletonDoubleCheckSafe {

    /**
     * 小明： 哎，这里多个volatile，它干啥的呢？
     * 老王： 等我给你百度下， 具有可见性、有序性，不具备原子性。
     * 小明： 说人话！啥是可见性？
     * 老王： 可见性是指当多个线程访问同一个变量时，一个线程修改了这个变量的值，其他线程能够立即看得到修改的值。
     * 小明： 好吧。。。不就是：多个线程共同偷窥一个弱女子，她的一举一动，大家都会看到。
     */
    private volatile static SingletonDoubleCheckSafe singletonDoubleCheckSafe;

    /**
     * 小明： 构造方法私有化，作用不说了。心累。
     * 老王： 。。。。。
     */
    private SingletonDoubleCheckSafe() {
    }

    /**
     * 小明： 乌拉乌拉，作用自己想吧。
     * 老王： 。。。。。。
     * @return
     */
    public static SingletonDoubleCheckSafe getInstance(){
        if(singletonDoubleCheckSafe == null){
            try {
                //模拟操作中的停顿
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 小明：
             * 不但加把锁，我还再里面判断一次，看你如何多偷我的线程。嘿嘿
             */
            synchronized (SingletonDoubleCheckSafe.class){
                if(singletonDoubleCheckSafe == null){
                    singletonDoubleCheckSafe = new SingletonDoubleCheckSafe();
                }
            }
        }
        return singletonDoubleCheckSafe;
    }
}
